<?php


namespace App\AppContext;

use App\Models\System\Hospital;
use App\Models\System\UserToken;
use ArrayAccess;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;
use function preg_match_all;

/**
 * 数据内容上下文
 */
abstract class Base
{
    const _USER_INFO_ = '_user_info_';
    static $instance;

    /**
     * 获取token
     * @return string
     */
    abstract function getToken(): string;

    /**
     * 获取当前APP
     * @return int
     */
    abstract function appId(): int;

    abstract function appName(): string;

    /**
     * 获取上下文中存储的值
     * @return array
     */
    abstract function all(): array;

    /**保存数据
     * @param array $value 上线问全部数据
     */
    abstract function save(array $value): void;

    /**
     * 销毁数据
     */
    abstract function destroy(): void;


    /**
     * 系统验证权限
     * @param $action
     * @param string $controller
     * @return bool
     */
    public function can($action, $controller = '')
    {

        if ($this->userId() == 1) return true;
        if (empty($controller)) {
            $rout = Route::getCurrentRoute()->getActionName();
            list($class) = explode('@', $rout);
            $preg = '#App\\\Http\\\Controllers\\\Admin\\\(.*?)Controller#is';
            $match = '';
            preg_match_all($preg, $class, $match);
            $controller = $match[1][0];
        }
        $controller = str_replace('_', '-', str_replace('\_', '/', Str::snake($controller)));
        $code = $controller. '@' . $this->_getActionName($action);
        $permissions = $this->get('permissions', []);
        Log::info('permissions:' . strtolower($code));
        Log::info('permissions:' . json_encode($permissions));
        return isset($permissions[strtolower($code)]);
    }

    function login($userInfo)
    {
        UserToken::query()->where('user_id', '=', $userInfo['id'])->where('token', '<>', $this->getToken())->delete();
        $token = UserToken::query()->where('user_id', '=', $userInfo['id'])->where('token', '=', $this->getToken())->first();
        if (empty($token)) {
            UserToken::create([
                'user_id' => $userInfo['id'],
                'token' => $this->getToken(),
            ]);
        }
        $this->setUserInfo($userInfo);
    }


    /**
     * 获取用户编号
     */
    function userId()
    {
        return $this->userInfo('id', 0);
    }

    /**
     * 角色
     * @return array
     */
    function roleId()
    {
        return $this->userInfo('role_id');
    }

    /**
     * 组
     * @return array
     */
    function groupCode()
    {
        return $this->userInfo('group_code');
    }

    /**
     * 获取用户信息
     * @param false $field
     * @param bool $defaultValue
     * @return array
     */
    function userInfo($field = false, $defaultValue = false)
    {
        if (empty($this->userInfo)) {
            $this->userInfo = $this->get(self::_USER_INFO_, []);
        }
        if ($field) {
            return Arr::get($this->userInfo, $field, $defaultValue);
        }
        return $this->userInfo;
    }

    /**
     * @param $key
     * @param $default
     * @return array|ArrayAccess|mixed
     */
    function get($key, $default = null)
    {
        return Arr::get($this->all(), $key, $default);
    }

    /**
     * 设置值
     * @param $key
     * @param $value
     */
    function set($key, $value)
    {
        $all = $this->all();
        $all[$key] = $value;
        $this->save($all);
    }

    /**
     * 获取当前医院
     * @param $id
     * @return array|ArrayAccess|int|mixed
     */
    function hospitalId($id = 0)
    {
        if ($id > 0) {
            $this->set('hospital_id', $id);
            $this->set('hospital_name', Hospital::query()->where('id', '=', $id)->value('name'));
            return $id;
        } else {
            return $this->get('hospital_id', 0);
        }
    }

    /**
     * 保存用户信息
     * @param $info
     */
    function setUserInfo($info)
    {
        $this->userInfo = $info;
        $this->set(self::_USER_INFO_, $info);
    }

    /**
     * 用户信息
     * @var array
     */
    private $userInfo;

    /**
     * 获取动作名称
     * @param $name
     * @return string
     */
    private function _getActionName($name)
    {
        if (Str::endsWith($name, '_view')) {
            $name = lcfirst(substr($name, 0, -4));
        }
        if (Str::endsWith($name, 'View')) {
            $name = lcfirst(substr($name, 0, -4));
        }
        if ($name == 'index' || $name == 'pager') {
            $name = 'index';
        } else if ($name == 'create' || $name == 'add' || $name == 'store' || $name == 'save') {
            $name = 'create';
        } else if ($name == 'update' || $name == 'edit') {
            $name = 'edit';
        } else if ($name == 'batchDelete' || $name == 'delete') {
            $name = 'delete';
        } else if ($name == 'show' || $name == 'read') {
            $name = 'show';
        }
        return $name;
    }
}
